package com.woniu.postbar.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.common.constant.PostBarConstant;
import com.woniu.common.entity.ResultCode;
import com.woniu.common.exception.LifeException;
import com.woniu.postbar.entity.dto.PostLikeCountDTO;
import com.woniu.postbar.entity.dto.PostLikeDTO;
import com.woniu.postbar.mapper.PostLikeMapper;
import com.woniu.postbar.mapper.UserPostMapper;
import com.woniu.postbar.pojo.PostLike;
import com.woniu.postbar.pojo.UserPost;
import com.woniu.postbar.service.DBService;
import com.woniu.postbar.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;


@Service
@Slf4j
public class DbServiceImpl implements DBService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private PostLikeMapper postLikeMapper;

    @Autowired
    private UserPostMapper userPostMapper;

    @Override
    public Boolean save(PostLike postLike) {
        int rows = postLikeMapper.insert(postLike);
        return rows > 0;
    }

    @Override
    public Boolean update(PostLike userLike) {
        UpdateWrapper<PostLike> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(PostBarConstant.USER_LIKE_DATE, userLike.getPostStatus());
        updateWrapper.set(PostBarConstant.USER_LIKE_UPDATETIME, userLike.getUpdateTime());
        updateWrapper.eq(PostBarConstant.USER_LIKE_ID, userLike.getId());
        int rows = postLikeMapper.update(userLike, updateWrapper);
        return rows > 0;
    }

    @Override
    public Page<PostLike> getLikedListByPostId(Integer postId, Integer currentPage, Integer pageSize) {
        // 分页获取喜欢列表信息
        Page<PostLike> result = new Page<>();
        result.setCurrent(currentPage);
        result.setSize(pageSize);
        // 获取内容的id查询点赞列表——查询都有谁给这个内容点赞过
        QueryWrapper<PostLike> queryWrapper = new QueryWrapper();
        queryWrapper.eq(PostBarConstant.USER_LIKE_POST_ID, postId);
        result = postLikeMapper.selectPage(result, queryWrapper);
        return result;
    }

    @Override
    public Page<PostLike> getLikedListByLikeUserId(Integer userId, Integer currentPage, Integer pageSize) {
        // 分页获取喜欢列表信息
        Page<PostLike> result = new Page<>();
        result.setCurrent(currentPage);
        result.setSize(pageSize);
        // 获取用户的id查询点赞列表——这个给谁点过赞
        QueryWrapper<PostLike> queryWrapper = new QueryWrapper();
        queryWrapper.eq(PostBarConstant.USER_LIKE_USER_ID, userId);
        result = postLikeMapper.selectPage(result, queryWrapper);
        return result;
    }

    @Override
    public PostLike getByPostIdAndLikeUserId(Integer postId, Integer userId) {
        HashMap<String, Object> map = new HashMap<>();
        map.put(PostBarConstant.USER_LIKE_POST_ID, postId);
        map.put(PostBarConstant.USER_LIKE_USER_ID, userId);
        try {
            //通过被点赞人和点赞人id查询是否存在点赞记录
            PostLike userLikes = postLikeMapper.selectByMap(map).get(0);
            return userLikes;
        } catch (Exception e) {
            //当前查询的被点赞人和点赞人id不存在点赞记录
            throw new LifeException(ResultCode.USER_COMMENT_STATUS_OPEN.getMessage());
        }
    }

    @Override
    public void transLikedFromRedisDB() {
        // 批量获取缓存中的点赞数据
        List<PostLikeDTO> list = redisService.getLikedDataFromRedis();
        // 为空，不写入
        if (CollectionUtils.isEmpty(list)) {
            throw new LifeException(ResultCode.USER_LIKE_STATUS_ERROR.getMessage());
        }
        for (PostLikeDTO item : list) {
            // 在数据库中查询
            PostLike userLikes = getByPostIdAndLikeUserId(item.getPostId(), item.getUserId());
            // 无记录，新增
            if (userLikes == null) {
                if (!save(userLikesDTOtoUserLikes(item))) {
                    throw new LifeException(ResultCode.USER_LIKE_INSERT.getMessage());
                }
            } else {
                // 有记录，更新
                // 判断数据库中点赞状态与缓存中点赞状态一致性
                if (userLikes.getPostStatus().equals(item.getPostStatus())) {
                    // 一致，无需持久化，点赞数量-1
                    redisService.decrementLikedCount(item.getPostId(), -1);
                } else {
                    // 不一致
                    if (userLikes.getPostStatus() == PostBarConstant.LIKE_STATUS_LIKE) {
                        // 在数据库中已经是点赞，则取消点赞，同时记得redis中的count-1
                        // 之前是点赞，现在改为取消点赞 1.设置更改status 2. redis中的count要-1（消除在数据库中自己的记录）
                        userLikes.setPostStatus(PostBarConstant.LIKE_STATUS_UNLIKE);
                        redisService.decrementLikedCount(item.getPostId(), -1);
                    } else if (userLikes.getPostStatus() == PostBarConstant.LIKE_STATUS_UNLIKE) {
                        // 未点赞，则点赞，修改点赞状态和点赞数据+1
                        userLikes.setPostStatus(PostBarConstant.LIKE_STATUS_LIKE);
                        redisService.decrementLikedCount(item.getPostId(), -1);
                    }
                    userLikes.setUpdateTime(new Date());
                    if (!update(userLikes)) {
                        // 更新点赞数据
                        throw new LifeException(ResultCode.USER_LIKE_INSERT.getMessage());
                    }
                }
            }
        }
    }

    @Override
    public void transLikedCountFromRedisDB() {
        // 获取缓存中内容的点赞数列表
        List<PostLikeCountDTO> list = redisService.getLikedCountFromRedis();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (PostLikeCountDTO item : list) {
            UserPost userPost = userPostMapper.selectById(item.getPostId());
            // 新增点赞数
            if (userPost != null) {
                Integer likeCount = userPost.getLikeCount() + item.getLikeCount();
                //内容id不为空，更新内容点赞数量
                userPost.setLikeCount(likeCount);
                UpdateWrapper<UserPost> updateWrapper = new UpdateWrapper<>();
                updateWrapper.set(PostBarConstant.LIKE_COUNT_DATE, userPost.getLikeCount());
                updateWrapper.eq(PostBarConstant.USER_LIKE_ID, userPost.getId());
                int rows = userPostMapper.update(userPost, updateWrapper);
                if (rows > 0) {
                    System.out.println(PostBarConstant.USER_LIKE_SUCCESS);
                }
            }
            System.out.println(PostBarConstant.USER_LIKE_NO_ID);
        }
    }

    private PostLike userLikesDTOtoUserLikes(PostLikeDTO userLikesDTO) {
        PostLike userLikes = new PostLike();
        userLikes.setId(userLikesDTO.getUserId());
        BeanUtils.copyProperties(userLikesDTO, userLikes);
        userLikes.setCreateTime(new Date());
        userLikes.setUpdateTime(new Date());
        return userLikes;
    }
}
